package affd.logic;

import java.util.ArrayList;

import net.htmlparser.jericho.CharacterEntityReference;
import net.htmlparser.jericho.CharacterReference;
import net.htmlparser.jericho.OutputDocument;
import net.htmlparser.jericho.Segment;

/**
 * A Text is a text modifier for segments. It allows to change the content
 * of the segment.
 * 
 * @author Joteitti joteitti@cc.hut.fi
 *
 */
public class Text {

	protected ArrayList<Segment> segments;
	protected ArrayList<Token> tokens;
	protected Tokenizer tokenizer;
	
	/**
	 * Constructs a text collection.
	 * 
	 * @param segments Segments to be processed.
	 * @param Tokenizer Tokenizer to be used.
	 */
	public Text(ArrayList<Segment> segments, Tokenizer tokenizer) {
		this.segments = segments;
		this.tokenizer = tokenizer;
		
		// Build tokens
		StringBuffer textBuffer = new StringBuffer();
		for(Segment segment : segments) {
			// Decode special characters
			if(segment instanceof CharacterEntityReference) {
				CharacterEntityReference character = (CharacterEntityReference) segment;
				textBuffer.append(CharacterReference.decode(character.getCharacterReferenceString()));
			}
			else {
				textBuffer.append(segment.toString());
			}
		}
		
		tokens = tokenizer.toTokens(textBuffer.toString());
	}
	
	/**
	 * Assigns the changes to the specified document.
	 * 
	 * @param document Document to be assigned.
	 * @param ignoreTokenTags Ignore token tags.
	 */
	public void assign(OutputDocument document, boolean ignoreTokenTags) {
		// Create html text
		StringBuffer htmlText = new StringBuffer();
		for(Token token : tokens) {
			// Html encoded content
			String encoded = token.getHtml(ignoreTokenTags);
			
			htmlText.append(encoded);
		}
		
		// Replace data
		for(int i = 0; i < segments.size(); i++) {
			document.replace(segments.get(i).getBegin(), segments.get(i).getEnd(), i == 0 ? htmlText : null);
		}
	}
	
	/**
	 * Returns the list of the tokens in the text.
	 * 
	 * @return List of tokens.
	 */
	public ArrayList<Token> getTokens() {
		return tokens;
	}
	
	/**
	 * Returns a string representation of this text.
	 */
	public String toString() {
		return segments.toString();
	}
}
